package com.chushouya.order.service.admin.impl;

import com.chushouya.order.dto.api.partnernotify.*;
import com.general.framework.core.exception.Ex;
import com.general.framework.core.lang.Check;
import com.general.framework.core.lang.Jsons;
import com.general.framework.core.lang.Strings;
import com.general.framework.core.lang.Validate;
import com.general.framework.core.utils.HttpClientUtil;
import com.chushouya.manager.dto.admin.clerk.ClerkInfoDTO;
import com.chushouya.manager.service.api.ClerkApiService;
import com.chushouya.order.constants.LogisticsTypeEnum;
import com.chushouya.order.constants.OrderStatusEnum;
import com.chushouya.order.constants.PartnerNotifyTypeKeys;
import com.chushouya.order.dao.entity.OrderEntity;
import com.chushouya.order.dao.entity.OrderExtendEntity;
import com.chushouya.order.dao.entity.OrderLogisticsEntity;
import com.chushouya.order.dao.repository.OrderExtendRepository;
import com.chushouya.order.dao.repository.OrderLogisticsRepository;
import com.chushouya.order.dao.repository.OrderRepository;
import com.chushouya.order.dto.admin.orderlogistics.OrderLogisticsQuery;
//=====order.dto.api.partnernotify.*;
import com.chushouya.order.dto.api.partnernotify.*;
import com.chushouya.order.service.admin.PartnerStatusNotifyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
public class PartnerStatusNotifyServiceImpl implements PartnerStatusNotifyService {

    @Resource
    private OrderRepository orderRepository;

    @Resource
    private OrderExtendRepository orderExtendRepository;

    @Resource
    private OrderLogisticsRepository orderLogisticsRepository;

    @Resource
    private ClerkApiService clerkApiService;



    private OrderEntity getOrder(Long orderId) {
        final OrderEntity orderEntity = orderRepository.selectByPrimaryKey(orderId);
        Check.notNull(orderEntity, "订单不存在");
        return orderEntity;
    }


    @Override
    public void controlOrderNotify(NotifyQueue dto) {
        final Long orderId = dto.getOrderId();
        final String notifyType = dto.getNotifyType();
        final String remark = dto.getRemark();
        final OrderEntity orderEntity = getOrder(orderId);
        log.info("订单推送通知 orderId:{},notifyType:{},remark:{}", orderId, notifyType, remark);
        OrderExtendEntity orderExtendEntity = orderExtendRepository.selectByOrderId(orderId);
        final String notifyUrl = orderExtendEntity.getNotifyUrl();
        if (Strings.isEmpty(notifyUrl)) {
            return;
        }

        switch (notifyType) {
            case PartnerNotifyTypeKeys.LOGIN:
                break;
            case PartnerNotifyTypeKeys.CREATE:
                createNotify(orderEntity,orderExtendEntity, notifyUrl, remark);
                break;
            case PartnerNotifyTypeKeys.DELIVERY:
                deliveryNotify(orderEntity, notifyUrl, remark);
                break;
            case PartnerNotifyTypeKeys.DISPATCH:
                dispatchNotify(orderEntity, notifyUrl, remark);
                break;
            case PartnerNotifyTypeKeys.CONFIRM:
                confirmNotify(orderEntity, notifyUrl, remark);
                break;
            case PartnerNotifyTypeKeys.VISIT:
                visitNotify(orderEntity, notifyUrl, remark);
                break;
            case PartnerNotifyTypeKeys.CANCEL:
                cancelNotify(orderEntity, notifyUrl, remark);
                break;
            case PartnerNotifyTypeKeys.COMPLETE:
                completeNotify(orderEntity, notifyUrl, remark);
                break;
            case PartnerNotifyTypeKeys.RECEIVE:
                receiveNotify(orderEntity, notifyUrl, remark);
                break;
            case PartnerNotifyTypeKeys.QUALITY:
                qualityNotify(orderEntity, notifyUrl, remark);
                break;
            default:
                throw Ex.business("未知的推送类型 {}", notifyType);
        }

    }
    @Override
    public void createNotify(OrderEntity orderEntity,OrderExtendEntity orderExtendEntity, String notifyUrl, String remark) {
        CreateNotifyDTO dto = new CreateNotifyDTO();
        dto.setPartnerOrderNo(orderEntity.getPartnerOrderNo());
        CreateNotifyDTO.CreateNotifyData data = new CreateNotifyDTO.CreateNotifyData();
        data.setOrderNo(orderEntity.getOrderNo());
        data.setPlatform(orderEntity.getPlatform());
        data.setOpenId(orderExtendEntity.getOpenId());
        data.setPhone(orderEntity.getUserPhone());
        dto.setData(data);
        requestPartner(notifyUrl, Jsons.toJSONString(dto));
    }

    @Override
    public void deliveryNotify(OrderEntity orderEntity, String notifyUrl, String remark) {
        final Long orderId = orderEntity.getOrderId();
        final OrderLogisticsEntity orderLogisticsEntity = getOrderLogistics(orderId);
        Validate.isNull(orderLogisticsEntity, "订单物流信息不存在");
        DeliveryNotifyDTO dto = new DeliveryNotifyDTO();
        dto.setPartnerOrderNo(orderEntity.getPartnerOrderNo());
        DeliveryNotifyDTO.DeliveryNotifyData data = new DeliveryNotifyDTO.DeliveryNotifyData();
        data.setDeliveryTime(orderEntity.getDeliveryTime());
        data.setExpressNo(orderLogisticsEntity.getExpressNo());
        data.setOrderStatus(OrderStatusEnum.WAIT_RECEIVE.value());
        data.setExpressCompany(orderLogisticsEntity.getExpressCompany());
        dto.setData(data);
        requestPartner(notifyUrl, Jsons.toJSONString(dto));
    }

    @Override
    public void dispatchNotify(OrderEntity orderEntity, String notifyUrl, String remark) {
        final Long clerkId = orderEntity.getClerkId();
        ClerkInfoDTO clerkInfoDTO = clerkApiService.getClerkInfo(clerkId);
        if (Objects.isNull(clerkInfoDTO)){
            throw Ex.business("业务员不存在");
        }
        DispatchNotifyDTO dto = new DispatchNotifyDTO();
        dto.setPartnerOrderNo(orderEntity.getPartnerOrderNo());
        DispatchNotifyDTO.DispatchNotifyData data = new DispatchNotifyDTO.DispatchNotifyData();
        data.setOrderStatus(OrderStatusEnum.WAIT_ACCEPT.value());
        data.setClerkName(clerkInfoDTO.getClerkName());
        data.setClerkPhone(clerkInfoDTO.getClerkPhone());
        data.setDispatchTime(orderEntity.getDispatchTime());
        data.setCity(clerkInfoDTO.getCity());
        dto.setData(data);
        requestPartner(notifyUrl, Jsons.toJSONString(dto));
    }

    @Override
    public void confirmNotify(OrderEntity orderEntity, String notifyUrl, String remark) {
        ConfirmNotifyDTO dto = new ConfirmNotifyDTO();
        dto.setPartnerOrderNo(orderEntity.getPartnerOrderNo());
        ConfirmNotifyDTO.ConfirmNotifyData data = new ConfirmNotifyDTO.ConfirmNotifyData();
        data.setOrderStatus(OrderStatusEnum.WAIT_VISIT.value());
        data.setConfirmTime(orderEntity.getConfirmTime());
        data.setRemark(remark);
        dto.setData(data);
        requestPartner(notifyUrl, Jsons.toJSONString(dto));
    }

    @Override
    public void visitNotify(OrderEntity orderEntity, String notifyUrl, String remark) {
        VisitNotifyDTO dto = new VisitNotifyDTO();
        dto.setPartnerOrderNo(orderEntity.getPartnerOrderNo());
        VisitNotifyDTO.VisitNotifyData data = new VisitNotifyDTO.VisitNotifyData();
        data.setOrderStatus(OrderStatusEnum.WAIT_QUALITY.value());
        data.setVisitTime(orderEntity.getVisitTime());
        data.setRemark(remark);
        dto.setData(data);
        requestPartner(notifyUrl, Jsons.toJSONString(dto));
    }

    @Override
    public void cancelNotify(OrderEntity orderEntity, String notifyUrl, String remark) {
        CanCelNotifyDTO dto = new CanCelNotifyDTO();
        dto.setPartnerOrderNo(orderEntity.getPartnerOrderNo());
        CanCelNotifyDTO.CanCelNotifyData data = new CanCelNotifyDTO.CanCelNotifyData();
        data.setOrderStatus(OrderStatusEnum.CANCELLED.value());
        if(Objects.isNull(orderEntity.getCloseTime())){
            data.setCancelTime(orderEntity.getCancelTime());
        }else{
            data.setCancelTime(orderEntity.getCloseTime());
        }
        data.setRemark(remark);
        dto.setData(data);
        requestPartner(notifyUrl, Jsons.toJSONString(dto));
    }

    @Override
    public void completeNotify(OrderEntity orderEntity, String notifyUrl, String remark) {
        CompleteNotifyDTO dto = new CompleteNotifyDTO();
        dto.setPartnerOrderNo(orderEntity.getPartnerOrderNo());
        CompleteNotifyDTO.CompleteNotifyData data = new CompleteNotifyDTO.CompleteNotifyData();
        data.setOrderStatus(OrderStatusEnum.COMPLETE.value());
        data.setCompleteTime(orderEntity.getCompleteTime());
        data.setCompletePrice(orderEntity.getCompletePrice());
        data.setRemark(remark);
        dto.setData(data);
        requestPartner(notifyUrl, Jsons.toJSONString(dto));
    }

    @Override
    public void receiveNotify(OrderEntity orderEntity, String notifyUrl, String remark) {
        ReceiveNotifyDTO dto = new ReceiveNotifyDTO();
        dto.setPartnerOrderNo(orderEntity.getPartnerOrderNo());
        ReceiveNotifyDTO.ReceiveNotifyData data = new ReceiveNotifyDTO.ReceiveNotifyData();
        data.setOrderStatus(OrderStatusEnum.WAIT_QUALITY.value());
        data.setReceiveTime(orderEntity.getReceiveTime());
        dto.setData(data);
        requestPartner(notifyUrl, Jsons.toJSONString(dto));
    }

    @Override
    public void qualityNotify(OrderEntity orderEntity, String notifyUrl, String remark) {

    }


    /**
     * 请求合作商接口
     */
    private void requestPartner(String notifyUrl, String paramsMap) {
        log.info("请求合作商接口 请求地址:{},请求参数:{}", notifyUrl, paramsMap);
        Map<String, String> header = new HashMap<>();
        header.put("content-type", "application/json;charset=UTF-8");
        try {
            String result = HttpClientUtil.httpPost(notifyUrl, header, paramsMap);
            log.info("请求合作商接口 返回结果:{}", result);
        } catch (Exception e) {
            log.error("请求合作商接口异常", e.getMessage());
        }
    }

    /**
     * 获取快递信息
     */
    private OrderLogisticsEntity getOrderLogistics(Long orderId) {
        OrderLogisticsQuery query = new OrderLogisticsQuery();
        query.setOrderId(orderId);
        query.setType(LogisticsTypeEnum.USER_SEND.value());
        return orderLogisticsRepository.selectOne(query);
    }
}
